using Sage.CloudStorage.Qiniu.Models;

namespace Sage.CloudStorage.Qiniu.Auth
{
    /// <summary>
    /// 七牛云认证提供者工厂类
    /// 提供便捷的静态方法来创建不同类型的七牛云认证提供者
    /// </summary>
    /// <remarks>
    /// **工厂模式的优势**：
    /// - **简化创建**：隐藏复杂的创建逻辑，提供简洁的API接口
    /// - **类型安全**：为不同场景提供专门的创建方法，避免参数错误
    /// - **配置合理**：确保创建的认证提供者配置正确和最优
    /// - **易于维护**：集中管理认证提供者的创建逻辑，便于后续扩展
    /// - **文档完整**：每个方法都包含详细的使用说明和最佳实践
    /// 
    /// **支持的认证类型**：
    /// - **管理API认证**：用于存储桶管理、文件管理等管理类操作
    /// - **上传认证**：用于文件上传场景，支持各种上传策略
    /// - **下载认证**：用于私有文件下载，生成临时访问链接
    /// - **流管理认证**：用于直播流管理和相关操作
    /// 
    /// **使用建议**：
    /// - 新项目优先使用V2版本的管理API认证
    /// - 根据具体业务场景选择合适的认证类型
    /// - 合理设置认证有效期，平衡安全性和用户体验
    /// - 在生产环境中妥善保管SecretKey，避免泄露
    /// </remarks>
    public static class QiniuAuthProviderFactory
    {
        /// <summary>
        /// 创建管理API认证提供者
        /// 用于七牛云存储桶管理、文件管理等管理类API的认证
        /// </summary>
        /// <param name="qiniuKey">七牛云密钥信息，包含AccessKey和SecretKey</param>
        /// <param name="useV2">是否使用V2版本签名算法，默认为true（强烈推荐）</param>
        /// <returns>配置好的管理API认证提供者</returns>
        /// <exception cref="ArgumentNullException">当qiniuKey为null时抛出</exception>
        /// <remarks>
        /// **签名版本选择**：
        /// 
        /// **V2版本（推荐）**：
        /// - **安全性更高**：包含HTTP方法、Host等更多请求信息
        /// - **防篡改能力强**：签名覆盖更多请求细节，难以伪造
        /// - **扩展性好**：支持自定义头部验证（X-Qiniu-*）
        /// - **标准化**：符合现代API安全标准和最佳实践
        /// - **兼容性好**：支持所有新版七牛云API
        /// 
        /// **V1版本（传统）**：
        /// - **兼容性考虑**：仅用于需要兼容旧版API的场景
        /// - **安全性较低**：签名信息相对简单
        /// - **功能限制**：不支持某些新特性
        /// 
        /// **适用场景**：
        /// - **存储桶操作**：创建、删除、列举存储桶
        /// - **文件管理**：删除、移动、复制、重命名文件
        /// - **元数据操作**：修改文件元数据、获取文件信息
        /// - **统计查询**：获取存储使用情况、流量统计等
        /// - **域名管理**：绑定、解绑自定义域名
        /// - **CDN配置**：缓存策略、防盗链设置等
        /// - **数据处理**：触发文件转码、截图等处理任务
        /// 
        /// **使用建议**：
        /// - 新项目强烈推荐使用V2版本
        /// - 除非有特殊兼容性要求，否则不建议使用V1版本
        /// - 在高安全性要求的场景中，务必使用V2版本
        /// 
        /// **使用示例**：
        /// ```csharp
        /// var qiniuKey = new QiniuKey("your_access_key", "your_secret_key");
        /// 
        /// // 推荐方式：使用V2版本（默认）
        /// var authV2 = QiniuAuthProviderFactory.CreateManageAuth(qiniuKey);
        /// 
        /// // 明确指定V2版本
        /// var authV2Explicit = QiniuAuthProviderFactory.CreateManageAuth(qiniuKey, true);
        /// 
        /// // 兼容旧版API（不推荐）
        /// var authV1 = QiniuAuthProviderFactory.CreateManageAuth(qiniuKey, false);
        /// ```
        /// </remarks>
        public static QiniuAuthProvider CreateManageAuth(QiniuKey qiniuKey, bool useV2 = true)
        {
            ArgumentNullException.ThrowIfNull(qiniuKey, nameof(qiniuKey));

            var authType = useV2 ? QiniuAuthType.ManageApiV2 : QiniuAuthType.ManageApi;
            return new QiniuAuthProvider(qiniuKey, authType);
        }

        /// <summary>
        /// 创建上传认证提供者
        /// 用于文件上传场景，自动生成上传策略并创建相应的认证提供者
        /// </summary>
        /// <param name="qiniuKey">七牛云密钥信息，包含AccessKey和SecretKey</param>
        /// <param name="bucket">目标存储桶名称</param>
        /// <param name="expiry">上传凭证有效期，默认为1小时</param>
        /// <returns>配置好的上传认证提供者</returns>
        /// <exception cref="ArgumentNullException">当qiniuKey为null时抛出</exception>
        /// <exception cref="ArgumentException">当bucket为null或空时抛出</exception>
        /// <remarks>
        /// **过时警告**：
        /// 此方法已标记为过时，推荐使用 `QiniuUploadPolicyFactory.CreateBasicUploadAuth` 方法替代。
        /// 新方法提供了更完整的上传策略支持和更灵活的配置选项。
        /// 
        /// **上传策略说明**：
        /// 上传策略是一个JSON文档，定义了上传的权限和限制条件，包括：
        /// - **scope**: 指定上传的目标存储桶（格式：bucket或bucket:key）
        /// - **deadline**: 上传凭证的过期时间（Unix时间戳）
        /// - **其他可选字段**: 文件大小限制、文件类型限制、回调设置等
        /// 
        /// **工作流程**：
        /// 1. **策略生成**：根据参数自动生成基础上传策略
        /// 2. **JSON序列化**：将策略对象序列化为JSON字符串
        /// 3. **认证创建**：创建Upload类型的认证提供者
        /// 4. **凭证生成**：认证提供者使用策略生成上传凭证
        /// 
        /// **适用场景**：
        /// - **客户端直传**：生成上传凭证供前端直接上传到七牛云
        /// - **服务端上传**：服务端代理上传文件到七牛云
        /// - **分片上传**：大文件的分片上传场景
        /// - **移动端上传**：移动应用的文件上传功能
        /// - **批量上传**：多文件上传场景
        /// 
        /// **安全特性**：
        /// - **时效性**：上传凭证有明确的过期时间，防止凭证滥用
        /// - **范围限制**：凭证只能用于指定的存储桶
        /// - **权限控制**：可以通过策略控制上传行为和限制
        /// 
        /// **注意事项**：
        /// - 上传凭证包含明文的上传策略，客户端可以解码查看
        /// - 建议根据实际需求设置合理的有效期（通常1-24小时）
        /// - 对于敏感的上传场景，可以在策略中添加额外的安全限制
        /// - 不要在客户端代码中硬编码SecretKey
        /// 
        /// **使用示例**：
        /// ```csharp
        /// var qiniuKey = new QiniuKey("your_access_key", "your_secret_key");
        /// var auth = QiniuAuthProviderFactory.CreateUploadAuth(
        ///     qiniuKey, 
        ///     "my-bucket", 
        ///     TimeSpan.FromHours(2)
        /// );
        /// ```
        /// 
        /// **推荐替代方法**：
        /// ```csharp
        /// var auth = QiniuUploadPolicyFactory.CreateBasicUploadAuth(
        ///     qiniuKey, 
        ///     "my-bucket", 
        ///     7200 // 2小时，单位：秒
        /// );
        /// ```
        /// </remarks>
        [Obsolete("请使用 QiniuUploadPolicyFactory.CreateBasicUploadAuth 方法替代，它提供了更完整的上传策略支持")]
        public static QiniuAuthProvider CreateUploadAuth(QiniuKey qiniuKey, string bucket, TimeSpan? expiry = null)
        {
            ArgumentNullException.ThrowIfNull(qiniuKey, nameof(qiniuKey));
            ArgumentException.ThrowIfNullOrEmpty(bucket, nameof(bucket));

            int expireInSeconds = expiry.HasValue ? (int)expiry.Value.TotalSeconds : 3600;
            var policy = UploadPolicy.CreateBasicPolicy(bucket, expireInSeconds);
            return new QiniuAuthProvider(qiniuKey, policy.ToJson());
        }

        /// <summary>
        /// 创建下载认证提供者
        /// 用于私有存储桶中文件的临时下载链接生成
        /// </summary>
        /// <param name="qiniuKey">七牛云密钥信息，包含AccessKey和SecretKey</param>
        /// <param name="expiry">下载链接的有效期</param>
        /// <returns>配置好的下载认证提供者</returns>
        /// <exception cref="ArgumentNullException">当qiniuKey为null时抛出</exception>
        /// <remarks>
        /// **下载认证原理**：
        /// 1. **过期时间添加**：为原始下载URL添加过期时间参数（e=Unix时间戳）
        /// 2. **签名计算**：对包含过期时间的URL进行HMAC-SHA1签名
        /// 3. **token生成**：将签名作为token参数添加到最终URL中
        /// 4. **服务器验证**：七牛云服务器验证签名的有效性和过期时间
        /// 
        /// **适用场景**：
        /// - **私有存储桶**：需要访问控制的文件下载
        /// - **付费内容**：需要权限验证的资源访问（如付费视频、文档）
        /// - **防盗链保护**：防止直链被恶意使用和批量下载
        /// - **临时分享**：生成有时效性的分享链接
        /// - **会员内容**：仅限会员访问的资源
        /// - **敏感资料**：需要审计和访问控制的文档
        /// - **企业文档**：内部文档的安全访问
        /// 
        /// **安全特性**：
        /// - **时效性控制**：链接在指定时间后自动失效，防止长期滥用
        /// - **签名验证**：防止URL参数被篡改，确保访问安全性
        /// - **访问控制**：只有知道完整签名URL的用户才能访问
        /// - **审计友好**：每次访问都需要重新生成，便于访问记录和统计
        /// 
        /// **有效期建议**：
        /// - **临时预览**：5-30分钟，适合快速查看和预览
        /// - **下载链接**：1-4小时，适合用户正常下载使用
        /// - **分享链接**：1-24小时，适合短期分享给他人
        /// - **长期访问**：不建议超过7天，长期有效会增加安全风险
        /// 
        /// **URL格式示例**：
        /// ```
        /// 原始URL: https://domain.com/file.jpg
        /// 签名URL: https://domain.com/file.jpg?e=1640995200&amp;token=AccessKey:签名
        /// ```
        /// 
        /// **注意事项**：
        /// - 生成的URL较长，包含签名信息，不适合手动输入
        /// - 仅适用于私有存储桶，公有存储桶通常不需要下载认证
        /// - 下载认证会直接修改请求的URL，不使用Authorization头部
        /// - 签名URL不应缓存太久，建议根据需要动态生成
        /// - 有效期过长会增加安全风险，过短可能影响用户体验
        /// 
        /// **使用示例**：
        /// ```csharp
        /// var qiniuKey = new QiniuKey("your_access_key", "your_secret_key");
        /// 
        /// // 30分钟有效期（适合临时预览）
        /// var auth = QiniuAuthProviderFactory.CreateDownloadAuth(
        ///     qiniuKey, 
        ///     TimeSpan.FromMinutes(30)
        /// );
        /// 
        /// // 4小时有效期（适合文件下载）
        /// var longAuth = QiniuAuthProviderFactory.CreateDownloadAuth(
        ///     qiniuKey, 
        ///     TimeSpan.FromHours(4)
        /// );
        /// ```
        /// </remarks>
        public static QiniuAuthProvider CreateDownloadAuth(QiniuKey qiniuKey, TimeSpan expiry)
        {
            ArgumentNullException.ThrowIfNull(qiniuKey, nameof(qiniuKey));

            return new QiniuAuthProvider(qiniuKey, expiry);
        }

        /// <summary>
        /// 创建流管理认证提供者
        /// 用于七牛云直播流管理API的认证
        /// </summary>
        /// <param name="qiniuKey">七牛云密钥信息，包含AccessKey和SecretKey</param>
        /// <returns>配置好的流管理认证提供者</returns>
        /// <exception cref="ArgumentNullException">当qiniuKey为null时抛出</exception>
        /// <remarks>
        /// **流管理功能**：
        /// 七牛云提供了完整的直播流管理服务，涵盖直播的全生命周期管理：
        /// 
        /// **核心功能**：
        /// - **流创建删除**：创建新的直播流，删除不需要的流
        /// - **推流拉流**：生成推流和拉流地址
        /// - **流状态管理**：查询和控制流的状态（启用/禁用）
        /// - **流量统计**：获取流量使用情况和统计数据
        /// 
        /// **高级功能**：
        /// - **直播录制**：自动录制直播内容到存储
        /// - **截图水印**：实时截图和添加水印
        /// - **转码适配**：多码率转码适配不同设备
        /// - **鉴权防盗**：推流和播放鉴权防止盗用
        /// 
        /// **认证特点**：
        /// - **Qiniu格式**：使用Qiniu格式的Authorization头
        /// - **请求体签名**：对完整的请求体进行带数据签名
        /// - **POST操作主导**：主要用于POST/PUT等写操作
        /// - **内容完整性**：签名包含完整的请求体内容，确保数据完整性
        /// 
        /// **适用场景**：
        /// - **直播平台**：管理主播的直播流，实现开播、关播等功能
        /// - **视频会议**：创建和管理视频会议的流媒体
        /// - **在线教育**：管理课程直播流，支持录制和回放
        /// - **游戏直播**：管理游戏直播流，支持高清低延迟
        /// - **企业直播**：管理企业内部直播和会议流
        /// - **活动直播**：大型活动的直播流管理
        /// 
        /// **API端点示例**：
        /// - **创建流**：`POST /v2/hubs/{hub}/streams`
        /// - **查询流状态**：`GET /v2/hubs/{hub}/streams/{stream}/status`
        /// - **禁用流**：`POST /v2/hubs/{hub}/streams/{stream}/disabled`
        /// - **获取推流地址**：`POST /v2/hubs/{hub}/streams/{stream}/rtmpPublishUrls`
        /// - **获取播放地址**：`POST /v2/hubs/{hub}/streams/{stream}/liveUrls`
        /// 
        /// **安全考虑**：
        /// - 流管理API通常涉及重要的业务操作，签名验证严格
        /// - 请求体包含敏感信息，必须进行完整性验证
        /// - 建议在服务端使用，避免在客户端暴露管理权限
        /// 
        /// **使用示例**：
        /// ```csharp
        /// var qiniuKey = new QiniuKey("your_access_key", "your_secret_key");
        /// var auth = QiniuAuthProviderFactory.CreateStreamManageAuth(qiniuKey);
        /// 
        /// // 配合HTTP客户端使用
        /// var request = new HttpRequestMessage(HttpMethod.Post, 
        ///     "https://pili.qiniuapi.com/v2/hubs/my-hub/streams");
        /// request.Content = new StringContent(streamConfig, Encoding.UTF8, "application/json");
        /// await auth.AuthenticateRequest(request);
        /// ```
        /// 
        /// **最佳实践**：
        /// - 流管理操作建议在服务端进行，确保安全性
        /// - 合理设置流的生命周期，避免资源浪费
        /// - 定期监控流状态，及时处理异常情况
        /// - 根据业务需求配置合适的录制和截图策略
        /// </remarks>
        public static QiniuAuthProvider CreateStreamManageAuth(QiniuKey qiniuKey)
        {
            ArgumentNullException.ThrowIfNull(qiniuKey, nameof(qiniuKey));

            return new QiniuAuthProvider(qiniuKey, QiniuAuthType.StreamManage);
        }
    }
}
